﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace TD
{
    public class TextureManager : ManagerBase<Texture2D>
    {
        public TextureManager(Game game) :
            base(game)
        {
            // Do something...
        }

        /// <summary>
        /// Get the default texture.
        /// </summary>
        /// <returns>The default texture.</returns>
        protected override Texture2D GetDefault()
        {
            return new Texture2D(base.Game.GraphicsDevice, 2, 2);
        }

        /// <summary>
        /// Load an additional item into the dictionary.
        /// </summary>
        /// <returns>The additional item.</returns>
        protected override KeyValuePair<string, Texture2D> AddItem()
        {
            Texture2D white = new Texture2D(Game.GraphicsDevice, 2, 2);
            white.SetData<Color>(new Color[4] { Color.White, Color.White, Color.White, Color.White });
            return new KeyValuePair<string,Texture2D>("white", white);
        }

        /// <summary>
        /// Load the texture with the given name into the manager.
        /// </summary>
        /// <param name="assetName">The name of the texture we want to load.</param>
        /// <returns>The texture as read from the texture file.</returns>
        protected override Texture2D LoadContent(string assetName)
        {
            try
            {
                string path = (Environment.CurrentDirectory + "\\textures\\" + assetName + ".png");
                if (File.Exists(path))
                {
                    FileAttributes attributes = File.GetAttributes(path);
                    if (attributes == FileAttributes.Archive)
                    {
                        Debug.WriteLine("Loading texture '" + assetName + "'...");

                        using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                        {
                            Texture2D texture = Texture2D.FromStream(base.Game.GraphicsDevice, stream);
                            //if (IsValid(ref texture, assetName))
                            {
                                return texture;
                            }
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Discarded texture! File attributes mismatched for texture: " + assetName);
                    }
                }
                else
                {
                    Debug.WriteLine("Discarded texture! Did not find texture with name: " + assetName);
                }
            }
            catch (SecurityException)
            {
                Debug.WriteLine("Texture '" + assetName + "' has not been loaded due to insufficient clearance.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine("An unknown error occured while loading '" + assetName + "' texture.");
#if DEBUG
                Debug.WriteLine(ex.GetType().ToString() + ": " + ex.Message);
#endif
            }

            return UseAsset("default");
        }

        /// <summary>
        /// Validate the texture.
        /// </summary>
        /// <param name="texture">The texture we want to validate.</param>
        /// <param name="assetName">The name of the asset.</param>
        /// <returns>True when the texture is valid.</returns>
        private bool IsValid(ref Texture2D texture, string assetName)
        {
            // Suffix for all the following errors.
            string suffix = ("Discarded texture! Texture '" + assetName + "'");

            // Ensure it is divisible by two. (Then these would just be zero!)
            int w = (texture.Width & 1);
            int h = (texture.Height & 1);

            // TextType.Error
            {
                if (w > 0 && h > 0)
                {
                    Debug.WriteLine(suffix + " has an odd width and height. The bounds should be divisible by two.");
                    return false;
                }
                else if (w > 0)
                {
                    Debug.WriteLine(suffix + " has an odd width. The width  should be divisible by two.");
                    return false;
                }
                else if (h > 0)
                {
                    Debug.WriteLine(suffix + " has an odd height. The height should be divisible by two.");
                    return false;
                }
            }

            // TextType.Warning
            {
                if (texture.Format != SurfaceFormat.Color)
                {
                    Debug.WriteLine(suffix + " has an invalid format. Expected ARGB.");
                }
            }

            // TextType.Regular
            return true;
        }
    }
}
